﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Entity;
using System.Linq.Expressions;

namespace DataAccess.Repository
{
    /// <summary>
    /// 视图访问基类，封装了FindEntity、FindList、Count等基本方法
    /// </summary>
    /// <typeparam name="TDbContext">数据操作上下文</typeparam>
    /// <typeparam name="TEntity">数据对象</typeparam>
    public class RepositoryViewFactory<TDbContext, TEntity>
        where TDbContext : DbContext, new()
        where TEntity : class, new()
    {
        protected DbContext dbContext;

        public RepositoryViewFactory()
        {
            dbContext = new TDbContext();
        }


        /// <summary>
        /// 根据主键查找一个实体
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns></returns>
        public TEntity FindEntity(object id)
        {
            return dbContext.Set<TEntity>().Find(id);
        }

        /// <summary>
        /// 根据条件查找一个实体
        /// </summary>
        /// <param name="predicate">条件</param>
        /// <returns></returns>
        public TEntity FindEntity(Expression<Func<TEntity, bool>> predicate)
        {
            return dbContext.Set<TEntity>().FirstOrDefault(predicate);
        }

        /// <summary>
        /// 对数据类型已知的特定数据源的查询进行计算的功能
        /// </summary>
        /// <returns></returns>
        public IQueryable<TEntity> IQueryable()
        {
            return dbContext.Set<TEntity>();
        }

        /// <summary>
        /// 对数据类型已知的特定数据源的查询进行计算的功能
        /// </summary>
        /// <param name="predicate">条件</param>
        /// <returns></returns>
        public IQueryable<TEntity> IQueryable(Expression<Func<TEntity, bool>> predicate)
        {
            return dbContext.Set<TEntity>().Where(predicate);
        }

        /// <summary>
        /// 根据sql查询列表
        /// </summary>
        /// <param name="sql">sql</param>
        /// <returns></returns>
        public List<TEntity> FindList(string sql)
        {
            return dbContext.Database.SqlQuery<TEntity>(sql).ToList<TEntity>();
        }

        /// <summary>
        /// 根据条件查询列表
        /// </summary>
        /// <param name="predicate">条件</param>
        /// <returns></returns>
        public List<TEntity> FindList(Expression<Func<TEntity, bool>> predicate)
        {
            return dbContext.Set<TEntity>().Where(predicate).ToList();
        }

        /// <summary>
        /// 根据条件统计记录总数
        /// </summary>
        /// <param name="predicate">条件</param>
        /// <returns></returns>
        public int Count(Expression<Func<TEntity, bool>> predicate)
        {
            return dbContext.Set<TEntity>().Count(predicate);
        }

        /// <summary>
        /// 统计记录总数
        /// </summary>
        /// <returns></returns>
        public int Count()
        {
            return dbContext.Set<TEntity>().Count();
        }
    }
}
